package com.fishingwithme.controllers;

import com.fishingwithme.domain.anybiting.CircleMessage;
import com.fishingwithme.domain.anybiting.CircleMessageService;
import com.fishingwithme.infrastructure.dtos.anybiting.CircleMessageResponseDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/circle-messages")
@Tag(name = "Circle Messages", description = "APIs for real-time and non-real-time circle messaging")
public class CircleMessageController {

    @Autowired
    private CircleMessageService messageService;


    /**
     * 准实时消息接口
     */
    @GetMapping("/quasi-realtime")
    @Operation(
            summary = "Get quasi real-time messages",
            description = "Retrieve quasi real-time messages for a specific city, with optional user cursor update"
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Messages retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = CircleMessageResponseDTO.class)
                    )
            )
    })
    public @ResponseBody List<CircleMessageResponseDTO> getQuasiRealTimeMessages(
            @Parameter(description = "City code", required = true, example = "110100")
            @RequestParam String cityCode,
            @Parameter(description = "Message limit", example = "20")
            @RequestParam(defaultValue = "20") int limit,
            @Parameter(description = "User ID for cursor update")
            @RequestParam(required = false) String userId) {

        List<CircleMessage> messages = messageService.getQuasiRealTimeMessages(cityCode, limit);
        if(CollectionUtils.isEmpty(messages)) {
            messages = messageService.getLatestByCircleIdAndCache(cityCode, limit);
        }
        if (userId != null) {
            String latestCursor = messageService.getLatestCursor(cityCode);
            messageService.updateUserCursor(cityCode, userId, latestCursor);
        }

        return messages.stream()
                .map(this::convertToResponseDTO)
                .collect(Collectors.toList());
    }

    /**
     * 非实时消息接口
     */
    @GetMapping("/non-realtime")
    @Operation(
            summary = "Get non real-time messages",
            description = "Retrieve non real-time messages with pagination using cursor"
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Messages retrieved successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = CircleMessageResponseDTO.class)
                    )
            )
    })
    public @ResponseBody List<CircleMessageResponseDTO> getNonRealTimeMessages(
            @Parameter(description = "City code", required = true, example = "110100")
            @RequestParam String cityCode,
            @Parameter(description = "Cursor for pagination")
            @RequestParam(required = false) String cursor,
            @Parameter(description = "Message limit", example = "20")
            @RequestParam(defaultValue = "20") int limit,
            @Parameter(description = "User ID for cursor update")
            @RequestParam(required = false) String userId,
            @Parameter(description = "Forward direction flag", example = "true")
            @RequestParam(defaultValue = "true") Boolean isForward) {

        List<CircleMessage> messages = messageService.getNonRealTimeMessages(cityCode, cursor, limit,isForward);
        if(CollectionUtils.isEmpty(messages)) {

        }
        if (userId != null && !messages.isEmpty()) {
            String newCursor = String.valueOf(messages.get(messages.size() - 1).getTimestamp().getTime());
            messageService.updateUserCursor(cityCode, userId, newCursor);
        }

        return messages.stream()
                .map(this::convertToResponseDTO)
                .collect(Collectors.toList());
    }

    private CircleMessageResponseDTO convertToResponseDTO(CircleMessage message) {
        CircleMessageResponseDTO dto = new CircleMessageResponseDTO();
        dto.setId(message.getId());
        dto.setCityCode(message.getCityCode());
        dto.setBizId(message.getBizId());
        dto.setMessageType(message.getType());
        dto.setSubtype(message.getSubType());
        dto.setContent(message.getContent());
        dto.setTimestamp(message.getTimestamp());
        dto.setSender(message.getSender());
        dto.setPriority(message.getPriority());
        dto.setCursor(String.valueOf(message.getTimestamp().getTime()));
        return dto;
    }
}
